﻿// -------------------------------------------------------------------------
//    @FileName         :    NFMagicTimeUtil.h
//    @Author           :    Gao.Yi
//    @Date             :   2022-09-18
//    @Email			:    445267987@qq.com
//    @Module           :    NFMagicTimeUtil.h
//
// -------------------------------------------------------------------------

/**
 * @file NFTimeUtility.h
 * @brief 时间实用工具类
 * 
 * 此文件提供了一套完整的时间处理工具函数，包括时区转换、日期计算、
 * 时间格式化、周期性检查等功能。主要用于游戏服务器中的时间逻辑处理。
 */

#pragma once

#include "NFStringUtility.h"
#include <stdlib.h>
#include <stdio.h>
#include "NFSocketLibFunction.h"

/** @brief 时间值类型定义，基于标准timeval结构 */
typedef struct timeval NFTimeVal;

#ifdef I18N_GLOBAL
#define LOCAL_TIME_CORRECTION  NFTimeUtility::GetTimeZoneOffset()  //本地时间时区偏移
#else
#define LOCAL_TIME_CORRECTION  NFTimeUtility::GetCurTimeZone() * 3600  //本地时间时区偏移
#endif

/**
 * @brief 时间相关常量枚举
 *
 * 定义了游戏开发中常用的时间常量，包括时区偏移、
 * 时间间隔和重置时间点等。
 */
enum
{
    /** @brief 一天的总秒数（24小时） */
    SECONDS_ADAY = 24 * 3600,
    /** @brief 一周的总秒数（7天） */
    SECONDS_AWEEK = 24 * 3600 * 7,
    /** @brief 一小时的总秒数 */
    SECONDS_AHOUR = 3600,
    /** @brief 半小时的总秒数 */
    SECONDS_HALF_AHOUR = 1800,
    /** @brief 一周的总小时数 */
    HOURS_AWEEK = 24 * 7,
    /** @brief 一个月的总秒数（按30天计算） */
    SECONDS_AMONTH = 24 * 3600 * 30,
    /** @brief 一年的总秒数（按365天计算） */
    SECONDS_AYEAR = 24 * 3600 * 365,
    /** @brief 游戏每日重置的小时数（凌晨4点） */
    GAME_RESET_HOUR_EVERYDAY = 4,
    /** @brief 游戏每周重置的小时数（凌晨4点） */
    GAME_RESET_HOUR_EVERYWEEK = 4,
    /** @brief 游戏每月重置的小时数（凌晨4点） */
    GAME_RESET_HOUR_EVERYMONTH = 4,
    /** @brief 游戏每日重置的分钟数 */
    GAME_RESET_MIN_EVERYDAY = 0,
    /** @brief 游戏每日重置的秒数 */
    GAME_RESET_SEC_EVERYDAY = 0,
};

/**
 * @brief TTimeVal小于比较操作符
 *
 * 比较两个时间值的大小，考虑微秒精度。
 *
 * @param lhs 左侧时间值
 * @param rhs 右侧时间值
 * @return bool lhs小于rhs时返回true
 */
inline bool operator<(const NFTimeVal& lhs, const NFTimeVal& rhs)
{
    return ((lhs.tv_sec - rhs.tv_sec) * 1000000 + (lhs.tv_usec - rhs.tv_usec)) < 0;
}

/**
 * @brief TTimeVal小于等于比较操作符
 *
 * @param lhs 左侧时间值
 * @param rhs 右侧时间值
 * @return bool lhs小于等于rhs时返回true
 */
inline bool operator<=(const NFTimeVal& lhs, const NFTimeVal& rhs)
{
    return !(rhs < lhs);
}

/**
 * @brief TTimeVal相等比较操作符
 *
 * @param lhs 左侧时间值
 * @param rhs 右侧时间值
 * @return bool lhs等于rhs时返回true
 */
inline bool operator==(const NFTimeVal& lhs, const NFTimeVal& rhs)
{
    return (!(lhs < rhs) && !(rhs < lhs));
}

/**
 * @brief TTimeVal减法操作符
 *
 * 计算两个时间值的差值，自动处理微秒借位。
 *
 * @param lhs 被减数时间值
 * @param rhs 减数时间值
 * @return TTimeVal 时间差值
 */
inline NFTimeVal operator-(const NFTimeVal& lhs, const NFTimeVal& rhs)
{
    NFTimeVal tvGap;
    tvGap.tv_sec = lhs.tv_sec - rhs.tv_sec;
    tvGap.tv_usec = lhs.tv_usec - rhs.tv_usec;

    if (tvGap.tv_usec < 0)
    {
        tvGap.tv_usec += 1000000;
        tvGap.tv_sec -= 1;
    }

    return tvGap;
}

/**
 * @brief 时间实用工具类
 * 
 * NFTimeUtility提供了丰富的时间处理功能，专门为游戏服务器设计。
 * 主要功能包括：
 * 
 * - 时区处理：GMT和本地时间的转换
 * - 日期计算：日、周、月的计算和比较
 * - 时间格式化：多种格式的时间字符串生成
 * - 周期检查：日更新、周更新、月更新检查
 * - 时间解析：字符串时间戳转换为Unix时间
 * 
 * 适用场景：
 * - 游戏日常更新逻辑
 * - 活动时间判断
 * - 日志时间格式化
 * - 玩家数据重置周期
 * 
 * 使用方法：
 * @code
 * // 获取当前本地时间
 * uint32_t localTime = NFTimeUtility::GetLocalTime();
 * 
 * // 检查是否需要日更新
 * bool needUpdate = NFTimeUtility::CheckDayUpdate(currentTime, lastUpdateTime);
 * 
 * // 格式化时间戳
 * std::string timeStr = NFTimeUtility::GetLocalTimeStampPrint();
 * 
 * // 判断是否是同一周
 * bool sameWeek = NFTimeUtility::CheckSameWeek(time1, time2);
 * @endcode
 */
class NFTimeUtility
{
public:
    /**
     * @brief 获取GMT时间偏移秒数
     * 
     * 获取当前时区相对于GMT（格林威治标准时间）的时差秒数。
     * 正数表示东时区，负数表示西时区。
     * 
     * @return uint32_t GMT时间偏移秒数
     */
    static uint32_t GetGmtSec();

    /**
     * @brief 判断是否为闰年
     *
     * 根据闰年规则判断指定年份是否为闰年：
     * - 能被4整除但不能被100整除的年份是闰年
     * - 能被400整除的年份是闰年
     *
     * @param year 年份
     * @return bool 如果是闰年返回true，否则返回false
     */
    static bool IsLeapYear(uint32_t year)
    {
        return ((0 == year % 4 && 0 != year % 100) || 0 == year % 400);
    }

    /**
     * @brief 获取当前服务器所在的时区偏移
     *
     * 获取当前服务器相对于UTC的时区偏移秒数。
     *
     * @return int32_t 时区偏移秒数（东时区为正，西时区为负）
     */
    static int32_t GetCurTimeZone();

public:
    /**
     * @brief 将时间（秒）转换为时:分:秒格式的std::string
     * @param myTime 时间值（单位：秒）
     * @return 格式化的时间字符串（HH:MM:SS格式）
     * @note 线程安全，推荐使用此版本替代CSecondToStr
     */
    static std::string SecondToStr(time_t myTime);

    /**
     * @brief 将时间转换为简化中文日期时间字符串
     *
     * 此函数将 time_t 类型的时间值转换为中文简体格式的日期时间字符串，
     * 便于中文用户界面显示。
     *
     * @param tMyTime 表示需要转换的时间（Unix 时间戳）
     * @return std::string 返回转换后的简化中文日期时间字符串
     *
     * @note 输出格式类似 "2023年12月25日 14:30:25"
     * @note 此方法线程安全，适合多线程环境使用
     */
    static std::string DateTimeToStrSimCn(time_t tMyTime);

    /**
     * @brief 将微秒精度的时间值转换为字符串
     *
     * 此函数将 NFTimeVal 类型的时间值转换为可读的字符串格式。
     * 输出格式通常为 "秒.微秒" 的形式，便于日志记录或调试使用。
     *
     * @param tvTime 表示需要转换的微秒精度时间值
     * @return std::string 返回转换后的时间字符串
     *
     * @note 此方法线程安全，适合多线程环境使用
     * @note 输出示例："1234567890.123456"
     */
    static std::string SecondTimeToStr(const NFTimeVal& tvTime);

    /**
     * @brief 将时间转换为日期时间字符串
     *
     * 此函数将 time_t 类型的时间值转换为标准的日期时间字符串格式。
     * 支持仅日期模式和完整日期时间模式。
     *
     * @param myTime 表示需要转换的时间（Unix 时间戳）
     * @param bOnlyDay 可选参数，若为 true，则仅转换为日期格式，默认为 false
     * @return std::string 返回转换后的日期时间字符串
     *
     * @note 此方法线程安全，适合多线程环境使用
     * @note 当 bOnlyDay 为 true 时，仅输出年月日信息
     */
    static std::string DateTimeToStr(time_t myTime, bool bOnlyDay = false);

    /**
     * @brief 将日期时间字符串转换为本地时间（新版本）
     *
     * 此函数将日期时间字符串转换为本地时间（以 time_t 表示）。
     *
     * @param pStr 表示日期时间字符串的字符数组
     * @param pTime 指向 time_t 类型变量的指针，用于存储转换后的时间
     * @return int 返回转换结果状态码
     */
    static int DataStrToLocalTimeNew(const char* pStr, time_t* pTime);

    /**
     * @brief 将日期字符串转换为本地时间
     *
     * 此函数将日期字符串转换为本地时间（以 time_t 表示）。
     *
     * @param pStr 表示日期字符串的字符数组
     * @param pTime 指向 time_t 类型变量的指针，用于存储转换后的时间
     * @return int 返回转换结果状态码
     */
    static int DateStrToLocalTime(const char* pStr, time_t* pTime);

    /**
     * @brief 获取时间的秒部分
     *
     * 此函数从日期时间字符串中提取时间的秒部分。
     *
     * @param pStr 表示日期时间字符串的字符数组
     * @param pTime 指向 time_t 类型变量的指针，用于存储提取的秒部分
     * @return int 返回提取结果状态码
     */
    static int GetTimeSec(const char* pStr, time_t* pTime);

    /**
     * @brief 扩展版本，获取时间的秒部分
     *
     * 此函数从日期时间字符串中提取时间的秒部分（扩展版本）。
     *
     * @param pStr 表示日期时间字符串的字符数组
     * @param pTime 指向 time_t 类型变量的指针，用于存储提取的秒部分
     * @return int 返回提取结果状态码
     */
    static int GetTimeSecEx(const char* pStr, time_t* pTime);

    /**
     * @brief 将日期时间字符串转换为time_t时间值
     *
     * 此函数解析格式为"yyyy-mm-dd hh:mm:ss"的日期时间字符串，
     * 并将其转换为对应的time_t时间值。
     *
     * @param szTime 指向日期时间字符串的指针，格式必须为"yyyy-mm-dd hh:mm:ss"
     * @return long 转换后的时间值，转换失败时返回-1
     *
     * @note 输入字符串必须严格遵循"yyyy-mm-dd hh:mm:ss"格式
     * @note 此方法为非静态成员函数，需要类实例调用
     * @warning 不检查指针有效性，调用者需要确保指针非空
     *
     * @see MakeTime(int, int, int, int, int, int) 参数分离版本
     */
    static long MakeTime(const char* szTime);

    /**
     * @brief 通过年月日时分秒参数创建time_t时间值
     *
     * 此函数根据提供的年、月、日、时、分、秒参数，
     * 构造并返回对应的time_t时间值。
     *
     * @param iYear 年份（如2023）
     * @param iMonth 月份（1-12）
     * @param iDay 日期（1-31）
     * @param iHour 小时（0-23）
     * @param iMinute 分钟（0-59）
     * @param iSecond 秒数（0-59）
     * @return time_t 构造后的时间值
     *
     * @note 输入参数应在有效范围内，超出范围的行为未定义
     * @note 此方法为非静态成员函数，需要类实例调用
     * @warning 不验证输入参数的有效性
     *
     * @see MakeTime(const char*) 字符串解析版本
     */
    static time_t MakeTime(int iYear, int iMonth, int iDay, int iHour, int iMinute, int iSecond);

    /**
    * @brief 将日期时间字符串转换为time_t时间值
    *
    * 此函数解析格式为"YYYY-MM-DD HH:MM:SS"的日期时间字符串，
    * 并将其转换为对应的time_t时间值。
    *
    * @param pTime 指向日期时间字符串的指针，格式必须为"YYYY-MM-DD HH:MM:SS"
    * @param ptime 指向time_t变量的指针，用于存储转换后的时间值
    * @return int 转换结果状态码，0表示成功，非0表示失败
    *
    * @note 输入字符串必须严格遵循"YYYY-MM-DD HH:MM:SS"格式
    * @note 转换失败时ptime的值未定义
    * @warning 不检查指针有效性，调用者需要确保两个指针都非空
    *
    * @see StrToTimePure(const char*) 简化版本，直接返回time_t值
    */
    static int StrToTime(const char* pTime, time_t* ptime);

    /**
     * @brief 将日期时间字符串转换为time_t时间值（纯净版本）
     *
     * 此函数解析格式为"YYYY-MM-DD HH:MM:SS"的日期时间字符串，
     * 直接返回对应的time_t时间值，无需额外参数。
     *
     * @param pTime 指向日期时间字符串的指针，格式必须为"YYYY-MM-DD HH:MM:SS"
     * @return time_t 转换后的时间值，转换失败时返回0
     *
     * @note 输入字符串必须严格遵循"YYYY-MM-DD HH:MM:SS"格式
     * @note 转换失败时返回0，无法区分是否为1970-01-01 00:00:00
     * @warning 不检查指针有效性，调用者需要确保指针非空
     *
     * @see StrToTime(const char*, time_t*) 完整版本，提供错误状态码
     */
    static time_t StrToTime(const char* pTime);

public:
    /**
     * @brief 根据Unix时间戳获取对应的年月日信息
     * @param iCurTime Unix时间戳（秒）
     * @param iYear [输出参数] 年份
     * @param iMonth [输出参数] 月份（1-12）
     * @param iMonthDay [输出参数] 月份中的天数（1-31）
     * @return 0 成功；-1 失败（月份计算异常）
     * @note 本算法适用于2013-01-01 00:00:00 ~ 2038年1月19日03:14:07之间的时间转换
     * @note 在I18N_GLOBAL宏定义下会自动加上本地时区偏移量
     * @note 从2013年开始计算以减少循环次数，提高性能
     * @warning 输入时间超出支持范围可能导致计算错误
     */
    static int GetCurDate(unsigned int iCurTime, int& iYear, int& iMonth, int& iMonthDay);

    /**
     * @brief 根据Unix时间戳获取对应的星期几和时分秒信息
     * @param iCurTime Unix时间戳（秒）
     * @param week [输出参数] 星期几（1-7，1为星期一，7为星期日）
     * @param hour [输出参数] 小时（0-23）
     * @param minute [输出参数] 分钟（0-59）
     * @param second [输出参数] 秒（0-59）
     * @return 0 成功
     * @note 在I18N_GLOBAL宏定义下会自动加上本地时区偏移量
     * @note 先计算星期几，再减去当天开始时间得到当天内的秒数
     * @note 用于游戏中需要按星期和具体时间进行逻辑判断的场景
     */
    static int GetCurTime(unsigned int iCurTime, int& week, int& hour, int& minute, int& second);

public:
    /***************Time计算**************************/
    /**
     * @brief 向时间值添加毫秒数（指针版本）
     *
     * 此函数向指定的时间值结构体添加毫秒数，自动处理微秒和秒之间的进位。
     * 使用指针传递，直接修改原始时间值。
     *
     * @param plhs 指向需要修改的时间值结构体的指针
     * @param iMs 要添加的毫秒数，可以为负数（表示减少时间）
     *
     * @note 此函数会自动处理微秒溢出到秒的进位
     * @note 输入的指针不能为空，否则会导致未定义行为
     * @warning 不检查指针有效性，调用者需要确保指针非空
     *
     * @see AddMs(NFTimeVal&, int) 引用版本
     */
    static void AddMsWithPointer(NFTimeVal* plhs, int iMs);

    /**
     * @brief 向时间值添加毫秒数（引用版本）
     *
     * 此函数向指定的时间值结构体添加毫秒数，自动处理微秒和秒之间的进位。
     * 使用引用传递，直接修改原始时间值。
     *
     * @param lhs 需要修改的时间值结构体的引用
     * @param iMs 要添加的毫秒数，可以为负数（表示减少时间）
     *
     * @note 此函数会自动处理微秒溢出到秒的进位
     * @note 相比指针版本更安全，避免了空指针问题
     *
     * @see AddMsWithPointer(NFTimeVal*, int) 指针版本
     */
    static void AddMs(NFTimeVal& lhs, int iMs);

    /**
     * @brief 向时间值添加微秒数（指针版本）
     *
     * 此函数向指定的时间值结构体添加微秒数，自动处理微秒和秒之间的进位。
     * 当微秒数超过1000000时会自动调整到秒字段。
     *
     * @param plhs 指向需要修改的时间值结构体的指针
     * @param iUs 要添加的微秒数，可以为负数（表示减少时间）
     *
     * @note 此函数会自动处理微秒溢出到秒的进位
     * @note 输入的指针不能为空，否则会导致未定义行为
     * @warning 不检查指针有效性，调用者需要确保指针非空
     *
     * @see AddUs(NFTimeVal&, int) 引用版本
     */
    static void AddUsWithPointer(NFTimeVal* plhs, int iUs);

    /**
     * @brief 向时间值添加微秒数（引用版本）
     *
     * 此函数向指定的时间值结构体添加微秒数，自动处理微秒和秒之间的进位。
     * 当微秒数超过1000000时会自动调整到秒字段。
     *
     * @param lhs 需要修改的时间值结构体的引用
     * @param iUs 要添加的微秒数，可以为负数（表示减少时间）
     *
     * @note 此函数会自动处理微秒溢出到秒的进位
     * @note 相比指针版本更安全，避免了空指针问题
     *
     * @see AddUsWithPointer(NFTimeVal*, int) 指针版本
     */
    static void AddUs(NFTimeVal& lhs, int iUs);

    /**
     * @brief 计算一天中指定时间点的已过秒数
     *
     * 此函数计算从当天00:00:00到指定时间点（小时:分钟:秒）的秒数。
     * 常用于游戏服务器中的时间计算和任务调度。
     *
     * @param iHour 小时数（0-23）
     * @param iMinute 分钟数（0-59）
     * @param iSecond 秒数（0-59）
     * @return int 从当天00:00:00开始计算的总秒数
     *
     * @note 此函数为非静态成员函数，需要类实例调用
     * @note 输入参数应在有效范围内，超出范围的行为未定义
     * @warning 不验证输入参数的有效性
     *
     * @example
     * @code
     * NFTimeUtil util;
     * int seconds = util.DayElapseSeconds(14, 30, 25); // 计算14:30:25的秒数
     * // 结果: 14*3600 + 30*60 + 25 = 52225秒
     * @endcode
     */
    static int DayElapseSeconds(int iHour, int iMinute, int iSecond);

    /**
     * @brief 计算两个时间值之间的毫秒差
     *
     * 此函数计算两个timeval结构体之间的时间差，返回毫秒数。
     * 常用于性能测量和时间间隔计算。
     *
     * @param pstTv1 指向第一个时间值的指针（较早时间）
     * @param pstTv2 指向第二个时间值的指针（较晚时间）
     * @return unsigned int 时间差的毫秒数（pstTv2 - pstTv1）
     *
     * @note 如果pstTv1晚于pstTv2，结果可能为负数但会被转换为无符号数
     * @warning 不检查指针有效性，调用者需要确保两个指针都非空
     *
     * @see TimeUsPass(struct timeval*, struct timeval*) 微秒级版本
     */
    static unsigned int TimeMsPass(timeval* pstTv1, timeval* pstTv2);

    /**
     * @brief 计算两个时间值之间的微秒差
     *
     * 此函数计算两个timeval结构体之间的时间差，返回微秒数。
     * 提供比毫秒更高的精度，适用于高精度时间测量。
     *
     * @param pstTv1 指向第一个时间值的指针（较早时间）
     * @param pstTv2 指向第二个时间值的指针（较晚时间）
     * @return int64_t 时间差的微秒数（pstTv2 - pstTv1），可能为负数
     *
     * @note 返回值为有符号64位整数，可以表示负的时间差
     * @warning 不检查指针有效性，调用者需要确保两个指针都非空
     *
     * @see TimeMsPass(struct timeval*, struct timeval*) 毫秒级版本
     */
    static int64_t TimeUsPass(timeval* pstTv1, timeval* pstTv2);

    /**
     * @brief 获取指定时间的小时数
     *
     * 从给定的 Unix 时间戳中提取小时（0-23）。
     *
     * @param iCurTime Unix 时间戳
     * @return int 小时数（0-23）
     */
    static int GetCurHour(time_t iCurTime);

    /**
     * @brief 获取指定时间的分钟数
     *
     * 从给定的 Unix 时间戳中提取分钟（0-59）。
     *
     * @param iCurTime Unix 时间戳
     * @return int 分钟数（0-59）
     */
    static int GetCurMin(time_t iCurTime);

    /**
     * @brief 判断两个时间是否为同一小时
     *
     * 判断两个时间戳是否在同一个小时内。
     *
     * @param tCur 当前时间
     * @param tBefore 对比的时间
     * @return bool 如果是同一小时返回true，否则返回false
     */
    static bool IsSameHour(time_t tCur, time_t tBefore);
    /**
     * @brief 检查指定时间间隔是否已过（秒级别）
     *
     * 判断从上次时间到现在是否已经过去了指定的秒数。
     *
     * @param tNow 当前时间
     * @param tLast 上次记录的时间
     * @param iGap 时间间隔（秒）
     * @return bool 如果时间间隔已过返回true，否则返回false
     *
     * @note 这是一个内联函数，性能较高
     * @note 常用于定时器和周期性任务的时间检查
     *
     * 使用示例：
     * @code
     * static time_t lastUpdate = 0;
     * time_t now = time(nullptr);
     * if (NFTimeUtility::IsTimePassedS(now, lastUpdate, 60)) {
     *     // 距离上次更新已经过去60秒
     *     lastUpdate = now;
     *     // 执行定时任务
     * }
     * @endcode
     */
    static bool IsTimePassedS(time_t tNow, time_t tLast, int iGap);

    /**
     * @brief 检查指定时间间隔是否已过（毫秒级别）
     *
     * 判断从上次时间到现在是否已经过去了指定的毫秒数。
     * 使用高精度的timeval结构进行计算。
     *
     * @param tvNow 当前时间（timeval结构）
     * @param tvLast 上次记录的时间（timeval结构）
     * @param iGapMs 时间间隔（毫秒）
     * @return bool 如果时间间隔已过返回true，否则返回false
     *
     * @note 这是一个内联函数，提供毫秒级精度
     * @note 用于需要高精度计时的场景
     *
     * 使用示例：
     * @code
     * static struct timeval lastFrame = {0, 0};
     * struct timeval now;
     * gettimeofday(&now, nullptr);
     * if (NFTimeUtility::IsTimePassedMS(now, lastFrame, 16)) {
     *     // 距离上次更新已经过去16毫秒（约60FPS）
     *     lastFrame = now;
     *     // 执行帧更新
     * }
     * @endcode
     */
    static bool IsTimePassedMs(timeval tvNow, timeval tvLast, int iGapMs);

    /**
     * @brief 将日期时间组件转换为时间戳
     *
     * 将年、月、日、时、分、秒各个组件转换为Unix时间戳。
     *
     * @param iYear 年份（如2023）
     * @param iMon 月份（1-12）
     * @param iMDay 月中的日期（1-31）
     * @param iHour 小时（0-23）
     * @param iMin 分钟（0-59）
     * @param iSec 秒（0-59）
     * @return time_t Unix时间戳
     *
     * @note 输入的日期时间组件必须有效，否则结果未定义
     */
    static time_t ToTimestamp(int iYear, int iMon, int iMDay/*day of the month */, int iHour, int iMin, int iSec);

    /**
     * @brief 获取距离下一个整点小时的秒数
     *
     * 计算当前时间距离下一个整点小时还有多少秒。
     *
     * @param tCur 当前时间
     * @return int 距离下一个整点的秒数（0-3599）
     *
     * 使用示例：
     * @code
     * time_t now = time(nullptr);
     * int seconds = NFTimeUtility::GetOffsetToNextHour(now);
     * // 如果现在是14:30:45，则返回1755秒（到15:00:00的秒数）
     * @endcode
     */
    static int GetOffsetToNextHour(time_t tCur);

    /**
     * @brief 获取距离下一个半小时整点的秒数
     *
     * 计算当前时间距离下一个半小时整点还有多少秒。
     * 半小时整点指xx:00:00和xx:30:00。
     *
     * @param tCur 当前时间
     * @return int 距离下一个半小时整点的秒数（0-1799）
     */
    static int GetOffsetToNextHalfHour(time_t tCur);

    /**
     * @brief 获取距离下一天零点的秒数
     *
     * 计算当前时间距离次日00:00:00还有多少秒。
     *
     * @param tCur 当前时间
     * @return int 距离下一天零点的秒数（0-86399）
     */
    static int GetOffsetToNextDay(time_t tCur);

    /**
     * @brief 解析并验证时间字符串格式，转换为Unix时间戳
     * @param pszTime 输入的时间字符串，期望格式为"YYYY-MM-DD HH:MM:SS"（长度必须为19）
     * @param dwUnixSec [输出参数] 解析成功后的Unix时间戳
     * @return 0 成功；-1 时间格式错误或解析失败
     * @note 该函数会进行双重验证：首先解析字符串为时间戳，然后将时间戳反向转换为字符串进行比对
     * @note 空字符串被视为未配置，返回成功但时间戳为0
     * @warning 时间字符串长度必须严格为19个字符，否则返回错误
     * @note CalcAndCheckTime("2024-01-15 10:30:45", timestamp) 返回0且timestamp为对应Unix时间戳
     */
    int CalcAndCheckTime(const std::string& pszTime, uint32_t& dwUnixSec);

    /**
     * @brief 获取给定时间的绝对周数
     *
     * 计算从1970年1月1日到给定时间的总周数。
     *
     * @param tTime 表示时间的时间_t类型变量
     * @return uint32_t 返回给定时间的绝对周数
     */
    static uint32_t GetAbsWeek(time_t tTime);

    /**
     * @brief 获取一天中的绝对秒数
     *
     * 此函数返回给定时间（以 time_t 表示）在一天中的绝对秒数。
     *
     * @param tTime 表示时间的 time_t 类型变量
     * @return uint32_t 返回一天中的绝对秒数
     */
    static uint32_t GetDayAbsSec(time_t tTime);

public:
    /*****************Day***********************/
    /**
     * @brief 判断两个时间是否为同一天（标准零点分界）
     *
     * 使用标准的零点（00:00:00）作为日期分界线判断两个时间是否为同一天。
     * 支持时间回退的情况。
     *
     * @param tCur 当前时间
     * @param tBefore 对比的时间
     * @param iHour
     * @return bool 如果是同一天返回true，否则返回false
     *
     * @note 使用标准时间，以零点为分界，支持回调
     */
    static bool IsSameDayStd(time_t tCur, time_t tBefore, int iHour);

    /**
     * @brief 判断两个时间是否为同一天（游戏重置时间分界）
     *
     * 使用游戏中定义的每日重置时间点作为日期分界线判断两个时间是否为同一天。
     * 与IsSameDayStd不同，此方法使用游戏特定的重置时间。
     *
     * @param tCur 当前时间
     * @param tBefore 对比的时间
     * @return bool 如果是同一天返回true，否则返回false
     *
     * @note 以每天GAME_RESET_HOUR_EVERYDAY点为准
     */
    static bool IsSameDay(time_t tCur, time_t tBefore);

    /**
     * @brief 判断两个时间是否为同一天（通用版本）
     *
     * 使用通用的算法判断两个时间戳是否在同一天内。
     * 此方法提供了一种标准化的同一天判断逻辑，可能考虑了特定的业务规则。
     *
     * @param tCur 当前时间戳
     * @param tBefore 对比的时间戳
     * @return bool 如果是同一天返回true，否则返回false
     *
     * @note 此方法的具体判断规则需要查看实现代码确定
     * @note 与其他IsSameDay系列方法可能在边界条件处理上有所不同
     */
    static bool IsSameDayCommon(time_t tCur, time_t tBefore);

    /**
     * @brief 判断两个时间是否为同一天（通用版本，不区分大小写）
     *
     * 使用通用算法判断两个时间戳是否在同一天内，与IsSameDayCommon类似，
     * 但在某些特定条件下可能有不同的处理逻辑（如不区分某些参数的大小写）。
     *
     * @param tCur 当前时间戳
     * @param tBefore 对比的时间戳
     * @return bool 如果是同一天返回true，否则返回false
     *
     */
    static bool IsSameDayCommonNoCase(time_t tCur, time_t tBefore);

    /**
    * @brief 获取指定时间在本日的秒数
    *
    * 此函数返回给定时间在本日的秒数（从 00:00:00 开始计数）。
    *
    * @param dwUnixSec 表示时间的 Unix 时间戳（单位为秒）
    * @param iHour
    * @return uint32_t 返回本日的秒数
    */
    static uint32_t GetCurDaySec(uint32_t dwUnixSec, int iHour = 0);

    /**
     * @brief 按 4 点算跨天，获取到 1970-01-01 的天数
     *
     * 此函数按凌晨 4 点作为跨天时间点，计算从 1970-01-01 到给定时间的天数。
     *
     * @param dwUnixSec 表示时间的 Unix 时间戳（单位为秒）
     * @param iHour
     * @return uint32_t 返回从 1970-01-01 起的天数
     */
    static uint32_t GetCurDay(uint32_t dwUnixSec, int iHour = 0);


    /**
     * @brief 获取今天开始时间（带偏移）
     *
     * 计算当天开始时间，可以指定秒数偏移量。
     *
     * @param tTimeNow 当前时间
     * @param iOffset 偏移的秒数
     * @return time_t 今天开始时间（加上偏移后）
     */
    static time_t GetTodayStartTimeWithOffset(time_t tTimeNow, int iOffset);

    /**
     * @brief 判断现在是否在指定时间的后1~n天
     *
     * 检查当前时间是否已经是指定时间的后1天及以上。
     * 天的临界点时间按指定的小时计算。
     *
     * @param tNow 当前时间
     * @param tTime 参考时间
     * @param iHour 日期分界的小时（默认为0，即凌晨0点）
     * @return bool 如果已经过了指定天数返回true，否则返回false
     */
    static bool IsAfterDayByUtcTime(time_t tNow, time_t tTime, int iHour = 0);

    /**
     * @brief 计算过去了多少天
     *
     * 计算从指定时间到当前时间过去了多少天。
     *
     * @param tNow 当前时间
     * @param tTime 起始时间
     * @param iHour 日期分界的小时（默认为0）
     * @return int 过去的天数
     */
    static int GetDayElapse(time_t tNow, time_t tTime, int iHour = 0);

    /**
     * @brief 计算绝对天数
     *
     * 以指定小时为分界计算天数。
     *
     * @param tNow 当前时间
     * @param iHour 日期分界的小时（默认为0）
     * @return uint32_t 绝对天数
     */
    static uint32_t GetAbsDay(time_t tNow, int iHour = 0);

    /**
     * @brief 获取以指定小时为基准的今天开始时间
     *
     * 计算以指定小时为起始点的今天开始时间。
     * 与GetTodayStartTime(time_t)不同，此方法允许自定义起始小时。
     *
     * @param tTimeNow 当前时间
     * @param iHour 起始小时（0-23）
     * @return time_t 今天在指定小时的开始时间
     */
    static time_t GetTodayStartTime(time_t tTimeNow, int iHour = 0);

    /**
     * @brief 获取今天结束时间
     *
     * 计算指定时间当天的结束时间，可以指定具体的小时作为结束时间点。
     * 结束时间指的是当天指定小时的00:00:00时刻。
     *
     * @param tTimeNow 指定的时间戳
     * @param iHour 结束的小时（默认为0，即次日凌晨0点）
     * @return time_t 今天结束时间的时间戳
     *
     * @note 当iHour为0时，返回次日00:00:00的时间戳
     * @note 当iHour为其他值时，返回当天指定小时的00:00:00时间戳
     *
     * 使用示例：
     * @code
     * time_t now = time(nullptr);
     * // 获取次日0点的时间戳（当天结束时间）
     * time_t endTime = NFTimeUtility::GetTodayEndTime(now);
     *
     * // 获取当天18点的时间戳
     * time_t end18 = NFTimeUtility::GetTodayEndTime(now, 18);
     * @endcode
     */
    static time_t GetTodayEndTime(time_t tTimeNow, int iHour = 0);

    /**
     * @brief 获取以指定小时和分钟为基准的今天开始时间
     *
     * 计算以指定小时和分钟为起始点的今天开始时间。
     * 提供更精确的时间控制。
     *
     * @param tTimeNow 当前时间
     * @param iHour 起始小时（0-23）
     * @param iMin 起始分钟（0-59）
     * @return time_t 今天在指定小时和分钟的开始时间
     */
    static time_t GetTodayStartTimeByMin(time_t tTimeNow, int iHour, int iMin);

    /**
     * @brief 计算两个时间相隔的天数
     *
     * 按照零点分界计算两个时间戳相隔的完整天数。
     * 结果可以为负数，表示时间顺序。
     *
     * @param tOne 第一个时间戳
     * @param tTwo 第二个时间戳
     * @return int 相隔的天数，tTwo比tOne晚则为正数，否则为负数
     *
     * @note 计算基于自然日，以午夜00:00:00为分界
     */
    static int GetDaysDelta(time_t tOne, time_t tTwo);

public:
    /**************Week*********************/
    /**
     * @brief 判断两个时间是否为同一周（标准零点分界）
     *
     * 使用标准的零点（00:00:00）作为日期分界线判断两个时间是否为同一周。
     * 以星期一为一周的开始，支持时间回退的情况。
     *
     * @param tNow 当前时间
     * @param tBeforeTime 对比的时间
     * @return bool 如果是同一周返回true，否则返回false
     *
     * @note 使用标准时间，以零点为分界，支持回调
     */
    static bool IsSameWeekStd(time_t tNow, time_t tBeforeTime);

    /**
     * @brief 获取指定时间的星期几
     *
     * 此函数返回给定时间是星期几，范围为 0-6（0 表示星期天）。
     *
     * @param tTime 表示时间的 time_t 类型变量
     * @return int 返回指定时间的星期几
     */
    static int GetWeekDay(time_t tTime);

    /**
     * @brief 获取时间是星期几（1-7格式）
     *
     * 获取指定时间是星期几，返回值范围为1-7。
     * 注意：1表示星期一，7表示星期天。
     *
     * @param tTime 指定的时间
     * @return int 星期几（1-7，1=星期一，7=星期天）
     */
    static int GetWeekDay127(time_t tTime);


    /**
     * @brief 获取本周开始时间（从星期一凌晨开始）
     *
     * 计算指定时间所在星期的开始时间，以星期一凌晨为准。
     * 可以指定具体的小时作为开始时间。
     *
     * @param tTime 指定的时间
     * @param iHour 开始的小时（默认为0，即凌晨0点）
     * @return time_t 本周开始的时间戳
     */
    static time_t GetWeekStartTime(time_t tTime, int iHour = 0);

    /**
     * @brief 获取本周结束时间（到星期天指定小时结束）
     *
     * 计算指定时间所在星期的结束时间，以星期天的指定小时为准。
     *
     * @param tTime 指定时间
     * @param iHour 结束的小时（默认为0）
     * @return time_t 本周结束的时间戳
     */
    static time_t GetWeekEndTime(time_t tTime, int iHour = 0);

    /**
     * @brief 获取本周开始时间（带偏移）
     *
     * 计算本周开始时间，可以指定秒数偏移量。
     *
     * @param tTime 指定时间
     * @param iOffset 偏移的秒数
     * @return time_t 本周开始时间（加上偏移后）
     */
    static time_t GetWeekStartTimeWithOffset(time_t tTime, int iOffset);

    /**
     * @brief 获取星期几（带偏移）
     *
     * 获取指定时间是星期几，可以指定秒数偏移量。
     *
     * @param tTime 指定时间
     * @param iOffset 偏移的秒数
     * @return time_t 考虑偏移后的星期信息
     */
    static time_t GetWeekDayWithOffset(time_t tTime, int iOffset);

    /**
     * @brief 获取两个时间之间相隔的周数
     *
     * 计算两个时间戳之间相隔多少个完整的周。
     *
     * @param tTime 起始时间
     * @param tNow 结束时间
     * @return int 相隔的周数
     */
    static int GetOffsetWeeks(time_t tTime, time_t tNow);

    /**
     * @brief 根据指定星期几和时间偏移计算本周内绝对时间戳
     * @param tNow 当前时间戳（GMT时间）
     * @param bWeekDay 目标星期几（1-7，1为星期一，7为星期日）
     * @param dwWeekTime 一周内的时间偏移（秒），从周一0点开始计算
     * @return 返回本周内指定星期几和时间的绝对时间戳
     * @note 计算基于本周的开始时间（周一0点）进行偏移
     * @note 如果bWeekDay超出1-7范围，计算结果可能不准确
     * @note GetAbsTimeByWeekDayAndTime(now, 3, 3600*10) 返回本周三上午10点的时间戳
     */
    static uint32_t GetAbsTimeByWeekDayAndTime(time_t tNow, uint8_t bWeekDay, uint32_t dwWeekTime);

    /**
     * @brief 判断是否是同一周（1-7星期格式）
     *
     * 判断两个时间是否在同一周内，以星期一凌晨开始计算。
     * 可以指定具体的开始小时。
     *
     * @param tNow 当前时间
     * @param tBeforeTime 对比时间
     * @param iHour 一周开始的小时（默认为0）
     * @return bool 如果是同一周返回true，否则返回false
     */
    static bool IsSameWeek127(time_t tNow, time_t tBeforeTime, int iHour = 0);

    /**
     * @brief 获取周循环链索引
     *
     * 按周循环链功能计算当前时间对应的链索引。
     * 用于实现基于周的循环功能。
     *
     * @param tNow 当前时间
     * @param iChainLength 链的长度
     * @return int 循环链中的索引
     */
    static int GetWeekCycleChainIndex(time_t tNow, int iChainLength);

    /**
     * @brief 根据星期索引获取星期字符串
     *
     * 将从0开始的星期索引转换为对应的星期字符串。
     *
     * @param bWeekDayIndex 星期索引（0-6，0表示星期日）
     * @return const char* 星期字符串表示
     *
     * @note 索引从0开始，0=星期日，1=星期一，依此类推
     * @note 返回的字符串可能是中文或英文，取决于具体实现
     */
    static std::string GetWeekDayStringByStartZero(uint8_t bWeekDayIndex);

    /**
     * @brief 根据起始小时获取星期索引
     *
     * 根据指定的起始小时计算当前时间的星期索引。
     * 允许自定义一天的开始时间，适用于游戏中非标准日期切换的需求。
     *
     * @param dwTimeNow 当前时间戳
     * @param bStartHour 一天的起始小时（0-23）
     * @return int 星期索引（0-6，0表示星期日）
     */
    static int GetWeekDayIndexWithStartHour(uint32_t dwTimeNow, uint8_t bStartHour);

    /**
     * @brief 检查星期控制标志是否匹配当前时间
     *
     * 根据星期控制标志检查当前时间是否在允许的星期范围内。
     * 用于实现基于星期的功能开关或活动控制。
     *
     * @param bWeekDayCtrlFlag 星期控制标志（位标志，bit0=星期日，bit1=星期一...bit6=星期六）
     * @param dwTimeNow 当前时间戳
     * @return bool 如果当前星期匹配控制标志返回true，否则返回false
     *
     * @note bWeekDayCtrlFlag是位标志，每一位代表一个星期
     * @note 例如：0x7F表示所有星期都开放，0x3E表示周一到周五开放
     */
    static bool IsOkWithWeekDayCtrl(uint8_t bWeekDayCtrlFlag, uint32_t dwTimeNow);

    /**
     * @brief 获取本周指定星期的开始时间
     *
     * 计算本周内指定星期几的00:00:00时间戳。
     * 如果指定的星期几就是今天或者还未到来，返回对应日期的开始时间。
     *
     * @param tNow 当前时间
     * @param iWeekDay 星期几（1-7，1表示星期一，7表示星期天）
     * @return time_t 指定星期的开始时间戳（该天的00:00:00）
     *
     * @note 如果指定的星期几已经过去，返回的是本周对应星期的时间
     */
    static time_t GetThisWeekDayTime(time_t tNow, int iWeekDay);

    /**
     * @brief 根据周数和星期几计算时间戳
     *
     * 根据指定的周数和星期几计算对应的时间戳。
     * 周数从某个基准点开始计算（通常是1970年1月1日所在的周）。
     *
     * @param ullWeek 周数（从基准点开始的周数）
     * @param iDay 星期几（1-7，1表示星期一）
     * @return uint64_t 计算得到的时间戳
     *
     * @note 基准点通常是Unix纪元时间（1970年1月1日）所在的周
     * @note 返回的是指定星期几的00:00:00时间戳
     */
    static uint64_t GetTimeByWeekDay(uint64_t ullWeek, int iDay);

    /**
     * @brief 根据服务器开服时间和开服天数计算对应的开服周数和星期几
     * @param dwServerOpenTime 服务器开服时间戳（秒）
     * @param iOpenDay 开服天数（从1开始计算）
     * @param iOpenWeek [输出参数] 计算得到的开服周数（从1开始）
     * @param iWeekDay [输出参数] 计算得到的星期几（1-7，1为星期一，7为星期日）
     * @note 用于游戏活动系统中按开服周期计算活动时间
     * @note 使用向上取整计算周数，确保第一周包含开服当天
     * @note 如果开服时间是星期三，第5天对应第2周星期日
     */
    static void GetOpenDayWeekInfo(uint32_t dwServerOpenTime, int iOpenDay, int& iOpenWeek, int& iWeekDay);

public:
    /***************Month*********************/
    /**
     * @brief 获取月中的日期
     *
     * 获取指定时间是当月的第几天。
     *
     * @param tTime 指定的时间
     * @return int 月中的日期（1-31）
     */
    static int GetMonthDay(time_t tTime);

    /**
     * @brief 获取指定时间的月份天数（带时区偏移）
     * @param tTime 输入的时间戳（GMT时间）
     * @param iTimeOffset 时区偏移量（秒），用于调整到本地时间
     * @return 返回该时间所在月份的第几天（1-31）
     * @note 该函数通过添加时区偏移来调整时间，然后获取本地时间的月份天数
     * @note 与NFTimeUtility::GetMonthDay功能类似，但支持自定义时区偏移
     * @warning 调用方需确保iTimeOffset参数的正确性，错误的偏移可能导致日期计算错误
     */
    static int GetMonthDay(time_t tTime, int iTimeOffset);

    /**
     * @brief 获取本月开始和结束时间
     * @param tTime 输入的时间戳
     * @param tBegin 输出参数，本月开始时间
     * @param tEnd 输出参数，本月结束时间
     * @param iHour 偏移小时数，默认从指定小时开始计算
     * @note 该函数会计算指定时间所在月份的开始和结束时间，支持时区偏移
     */
    static void GetMonthStartEndTime(time_t tTime, time_t& tBegin, time_t& tEnd, int iHour = 0);

    /**
     * @brief 获取本月开始时间
     * @param tTime 输入的时间戳
     * @param iHour 偏移小时数，从指定小时开始计算月份
     * @return 返回本月开始时间的时间戳，失败返回0
     * @note 计算指定时间所在月份的第一天指定小时的时间戳
     */
    static time_t GetMonthStartTime(time_t tTime, int iHour = 0);

    /**
     * @brief 获取本月结束时间
     * @param tTime 输入的时间戳
     * @param iHour 偏移小时数，从指定小时开始计算月份
     * @return 返回本月结束时间的时间戳，失败返回0
     * @note 计算指定时间所在月份的下个月第一天指定小时的时间戳
     * @warning 对于2月份只考虑了28天的情况，未处理闰年29天的case
     */
    static time_t GetMonthEndTime(time_t tTime, int iHour = 0);

    /**
    * @brief 判断两个时间戳是否在同一个月（标准版本）
    * @param tNow 当前时间戳（GMT时间）
    * @param tBeforeTime 之前的时间戳（GMT时间）
    * @param iHour 偏移小时数，用于调整月份计算的起始时间点
    * @return true 如果两个时间在同一个月，false 否则
    * @note 通过比较两个时间各自所在月份的开始时间来判断是否为同月
    * @note 支持时区偏移和自定义月份起始小时
    */
    static bool IsSameMonthStd(time_t tNow, time_t tBeforeTime, int iHour = 0);

    /**
     * @brief 检查两个时间是否在同一个月
     *
     * 判断两个时间戳是否属于同一个月份，使用标准的月份边界。
     *
     * @param tCur 当前时间
     * @param tBefore 对比的时间
     * @return bool 如果在同一个月返回true，否则返回false
     */
    static bool IsSameMonth(time_t tCur, time_t tBefore);

    /**
     * @brief 获取指定年月的天数
     *
     * 计算指定年份和月份有多少天，自动考虑闰年情况。
     *
     * @param year 年份
     * @param month 月份（1-12）
     * @return short 该月的天数（28-31）
     *
     * @note 会正确处理闰年的2月份（29天 vs 28天）
     */
    static short GetCurMonthDay(int year, int month);

    /**
     * @brief 获取下个月的指定日期
     *
     * 计算相对于当前年月日的下个月对应日期。
     * 如果下个月没有对应的日期（如1月31日的下个月），会进行适当调整。
     *
     * @param year 当前年份
     * @param month 当前月份（1-12）
     * @param day 当前日期（1-31）
     * @param nMonth [out] 输出的目标月份
     * @return int64_t 下个月对应日期的时间戳表示
     *
     * @note 当前月份的日期在下个月不存在时（如1月31日），会调整到下个月的最后一天
     */
    static int64_t GetNextMonthDay(int year, int month, int day, int& nMonth);

    /**
     * @brief 计算两个时间戳之间相差的月数
     * @param dwTimeNow 当前时间戳（秒）
     * @param dwTimeLast 过去的时间戳（秒）
     * @return 相差的月数，如果当前时间早于过去时间则返回-1
     * @note 计算时会根据游戏重置时间进行调整，确保按游戏逻辑计算月份差异
     * @warning 当前时间早于过去时间时返回-1，调用方需要进行有效性检查
     */
    static int GetElapseMonths(uint32_t dwTimeNow, uint32_t dwTimeLast);

public:
    /***************Year*********************/

    /**
     * @brief 判断两个时间是否为同一年
     *
     * 判断两个时间戳是否属于同一个年份，使用标准的年份边界。
     *
     * @param tCur 当前时间
     * @param tBefore 对比的时间
     * @param iHour
     * @return bool 如果在同一年返回true，否则返回false
     */
    static bool IsSameYearStd(time_t tCur, time_t tBefore, int iHour = 0);

    /**
    * @brief 判断两个时间是否为同一年
    *
    * 判断两个时间戳是否属于同一个年份，使用标准的年份边界。
    *
    * @param tCur 当前时间
    * @param tBefore 对比的时间
    * @return bool 如果在同一年返回true，否则返回false
    */
    static bool IsSameYear(time_t tCur, time_t tBefore);

    /**
     * @brief 获取从今年 1 月 1 日到目前的天数
     *
     * 此函数返回从今年 1 月 1 日到给定时间的天数，范围为 0-365。
     *
     * @param tTime 表示时间的 time_t 类型变量
     * @return uint16_t 返回从今年 1 月 1 日到目前的天数
     */
    static uint16_t GetYearDay(time_t tTime);

    /**
     * @brief 获取本年开始时间
     *
     * 计算指定时间所在年份的开始时间。
     * 可以指定具体的小时作为开始时间。
     *
     * @param tTime 指定的时间
     * @param iHour 开始的小时（默认为0，即凌晨0点）
     * @return time_t 本年开始的时间戳（1月1日指定小时的时间）
     */
    static time_t GetYearStartTime(time_t tTime, int iHour = 0);

    /**
     * @brief 获取本年结束时间
     *
     * 计算指定时间所在年份的结束时间。
     * 可以指定具体的小时作为结束时间。
     *
     * @param tTime 指定的时间
     * @param iHour 结束的小时（默认为0，即凌晨0点）
     * @return time_t 本年结束的时间戳（12月31日指定小时的时间）
     */
    static time_t GetYearEndTime(time_t tTime, int iHour = 0);

    /**
     * @brief 获取时间戳对应的年份
     *
     * 从Unix时间戳中提取实际的年份值（公历年份）。
     *
     * @param tCur 时间戳
     * @return int 年份值（如2023）
     *
     * @note 返回的是实际的年份数字，不是相对于1900的偏移
     */
    static int GetYear(time_t tCur);

public:
#ifdef I18N_GLOBAL
    /**
     * @brief 获取当前的时区偏移量
     *
     * 此函数返回当前设置的时区偏移量（以小时为单位）。
     *
     * @return int 返回当前的时区偏移量
     *
     * @note 此函数适用于需要动态调整时区的场景
     */
    static int GetTimeZoneOffset();

    /**
     * @brief 设置时区偏移量
     *
     * 此函数用于设置时区偏移量（以小时为单位）。
     *
     * @param iTimeOffset 表示新的时区偏移量（以小时为单位）
     *
     * @note 设置的偏移量会影响时间相关的计算
     */
    static void SetTimeZoneOffset(int iTimeOffset);
#endif

    /**
     * @brief 获取绝对天数偏移量
     *
     * 此函数返回当前系统或游戏中使用的绝对天数计算偏移量。
     * 绝对天数偏移量用于调整从1970年1月1日开始计算的天数基准，
     * 以适应不同的时区或游戏逻辑需求。
     *
     * @return int 绝对天数偏移量（单位：天）
     *
     * @note 偏移量可能基于时区配置或游戏特定的时间基准
     * @note 返回值会影响GetAbsDay等相关函数的计算结果
     *
     * @see GetAbsDay(time_t, int) 获取绝对天数
     */
    static int GetAbsDayOffSet();

    /**
     * @brief 获取绝对周数偏移量
     *
     * 此函数返回当前系统或游戏中使用的绝对周数计算偏移量。
     * 绝对周数偏移量用于调整从1970年1月1日开始计算的周数基准，
     * 通常用于适应不同的周开始日期或游戏逻辑需求。
     *
     * @return int 绝对周数偏移量（单位：周）
     *
     * @note 偏移量可能基于时区配置或游戏特定的周计算逻辑
     * @note 返回值会影响GetAbsWeek等相关函数的计算结果
     *
     * @see GetAbsWeek(time_t) 获取绝对周数
     */
    static int GetAbsWeekOffSet();

    /**
     * @brief 计算当前时区偏移量
     *
     * 此函数计算并返回当前系统时区相对于UTC的偏移量。
     * 用于在时间计算中自动适配本地时区，确保时间处理的准确性。
     *
     * @return int 时区偏移量（单位：秒），正数表示东时区，负数表示西时区
     *
     * @note 函数会自动检测系统时区设置
     * @note 返回值为秒数，如GMT+8时区返回28800（8*3600）
     * @note 在跨时区部署的系统中，建议统一使用UTC时间避免混乱
     *
     * @warning 系统时区变更后可能需要重启程序才能获取最新值
     */
    static int CountCurTimeZone();

private:
#ifdef I18N_GLOBAL
    static int m_iStaticTimeOffset;
#endif
    static int m_iTimeAbsDayOffSet; // 绝对天数偏移
    static int m_iTimeAbsWeekOffSet; // 绝对周数偏
    static int m_iCurTimeZone;
};

